﻿package com.sense.utils
{
		
	import fl.transitions.*;
	import fl.transitions.easing.*;
	
	import flash.display.*;
	import flash.events.*;
	import flash.geom.*;
	import flash.net.*;
	import flash.text.*;
	import flash.utils.Timer;
	
	import gs.TweenLite;
	
	public class BitmapManipulator 
	{

		static var childArray:Array = [];
		static var timerIsSet:Boolean = false;
		static var faderTimer:Timer;

		public function BitmapManipulator() 
		{
			throw new Error("The MC to bitmap class is not intended to be instantiated.");
		}
		
       public static function mcToBitmap(mc, smoothing:Boolean = true, x:Number=0, y:Number=0, w:Number=0, h:Number=0, scale:Number=1):Bitmap 
       {
           	
			// create cropping rectangle and base point
			var rect:Rectangle = new Rectangle(x, y, w, h);
			var pt:Point = new Point(0, 0);
			var original_image:BitmapData = new BitmapData(mc.width, mc.height, true, 0x0000FF);
			var mat:Matrix = new Matrix();
			mat.scale(scale, scale)
			original_image.draw(mc, mat);
			var copyObject:BitmapData = new BitmapData(w-x, h-y, true, 0x0000FF);
			copyObject.copyPixels(original_image, rect, pt)
			var returnBitmap:Bitmap = new Bitmap(copyObject, "auto", smoothing);
			original_image.lock();
			copyObject.lock();
			original_image.dispose();
			return returnBitmap;
        }
	
		
		public static function simpleMcToBitmap(mc):Bitmap 
		{
			// create cropping rectangle and base point
			var rect:Rectangle = new Rectangle(0, 0, mc.width, mc.height);
			var pt:Point = new Point(0, 0);
			var original_image:BitmapData = new BitmapData(mc.width, mc.height, true, 0x0000FF);
			var mat:Matrix = new Matrix();
			original_image.draw(mc, mat);
			var copyObject:BitmapData = new BitmapData(mc.width, mc.height, true, 0x0000FF);
			copyObject.copyPixels(original_image, rect, pt)
			var returnBitmap:Bitmap = new Bitmap(copyObject, "auto", true);
			original_image.lock();
			copyObject.lock();
			original_image.dispose();
			return returnBitmap;
		}
		

		public static function fadeChild( childParent:Object, child:Object, seconds:int ) 
		{
			
			child.alpha = 0;
			childParent.addChild(child);
			childArray.unshift( child );
			
			if (!timerIsSet) 
			{
				timerIsSet = true;
				faderTimer = new Timer(200, 0);
				faderTimer.addEventListener("timer", fadeIn);
				faderTimer.start();
			}
			
			function fadeIn(e:Event) 
			{
				var fadeElement = childArray.pop();
				if (childArray.length == 0) ;
				{
					faderTimer.stop();
					timerIsSet = false;
				}
				
				fadeElement.addEventListener(Event.ENTER_FRAME, doFadeIn);
			}
			
			function doFadeIn(e:Event) 
			{
				e.target.alpha += 0.1;
				
				if (e.target.alpha > 1) 
				{
					e.target.removeEventListener(Event.ENTER_FRAME, doFadeIn);
				}
			}
		}
		
		
		public static function wipeIn(mc, type:String = 'sideWipeIn') 
		{
			
			var speed = 0.1;
			var friction = 1.1;
			var maskShape:Shape = new Shape();
			var tW = mc.width;
			var tH = mc.height;
			var count = 0;
			
			mc.addChild(maskShape);
			mc.mask = maskShape;
					
			mc.addEventListener(Event.ENTER_FRAME, doWipeIn);
			
			function doWipeIn(e:Event) 
			{
				
				switch (type) 
				{
					case ('sideWipeIn') :
						// to the left
						
						speed *= friction;
						count += speed;
						
						maskShape.graphics.clear();
						maskShape.graphics.lineStyle(1, 0xFFFFFF, 1);
						maskShape.graphics.beginFill(0xFFFFFF, 1);
						maskShape.graphics.lineTo(tW * count/1.5, 0);
						maskShape.graphics.curveTo(tW, tH, 0, tH * count/1.5);
						maskShape.graphics.lineTo(0, 0);
						break;
					
					case ('sideWipeIn2') :
						// to the right
						
						speed *= friction;
						count += speed;
						
						maskShape.graphics.clear();
						maskShape.graphics.lineStyle(1, 0xFFFFFF, 1);
						maskShape.graphics.beginFill(0xFFFFFF, 1);
						maskShape.graphics.moveTo(tW, 0);
						maskShape.graphics.lineTo(tW - (tW * count/1.5), 0);
						maskShape.graphics.curveTo(0, tH, tW, tH * count/1.5);
						maskShape.graphics.lineTo(tW, 0);
						break;
					
					case ('topWipeIn') :
					
						speed *= friction;
						count += speed;
						
						maskShape.graphics.clear();
						maskShape.graphics.lineStyle(1, 0xFFFFFF, 1);
						maskShape.graphics.beginFill(0xFFFFFF, 1);
						maskShape.graphics.lineTo(tW, 0);
						maskShape.graphics.lineTo(tW, tH * count );
						maskShape.graphics.curveTo(tW * count, tH * count, 0, tH * (count/2));
						maskShape.graphics.lineTo(0, 0);
						break;
					case ('leftWipeIn') :
					
						speed *= friction;
						count += speed;
						
						maskShape.graphics.clear();
						maskShape.graphics.lineStyle(1, 0xFFFFFF, 1);
						maskShape.graphics.beginFill(0xFFFFFF, 1);
						maskShape.graphics.lineTo(tW * count, 0);
						maskShape.graphics.lineTo(tW * count, tH );
						maskShape.graphics.lineTo(0, tH);
						maskShape.graphics.lineTo(0, 0);
						break;
					
					default:
						break;
				}

				if (count > 1.5) 
				{
					mc.removeEventListener(Event.ENTER_FRAME, doWipeIn);
					mc.mask = null;
					mc.removeChild(maskShape);
				}
			}
		}
		
		public static function remove(mc, type:String = 'sideWipeOut') 
		{
			
			var speed = 0.5;
			var friction = 1.1;
			var maskShape:Shape = new Shape();
			var tW = mc.width;
			var tH = mc.height;
			var count = 1.5;
			
			mc.addChild(maskShape);
			mc.mask = maskShape;
					
			mc.addEventListener(Event.ENTER_FRAME, doWipeOut);
			
			function doWipeOut(e:Event) 
			{
				
				switch (type) 
				{
					case ('sideWipeOut') :
						// to the left
						
						speed *= friction;
						count -= speed;
						
						maskShape.graphics.clear();
						maskShape.graphics.lineStyle(1, 0xFFFFFF, 1);
						maskShape.graphics.beginFill(0xFFFFFF, 1);
						maskShape.graphics.lineTo(tW * count/1.5, 0);
						maskShape.graphics.curveTo(tW, tH, 0, tH * count/1.5);
						maskShape.graphics.lineTo(0, 0);
						break;
					
					case ('sideWipeOut2') :
						// to the right
						
						speed *= friction;
						count += speed;
						
						maskShape.graphics.clear();
						maskShape.graphics.lineStyle(1, 0xFFFFFF, 1);
						maskShape.graphics.beginFill(0xFFFFFF, 1);
						maskShape.graphics.moveTo(tW, 0);
						maskShape.graphics.lineTo(tW - (tW * count/1.5), 0);
						maskShape.graphics.curveTo(0, tH, tW, tH * count/1.5);
						maskShape.graphics.lineTo(tW, 0);
						break;
					
					case ('topWipeOut') :
					
						speed *= friction;
						count += speed;
						
						maskShape.graphics.clear();
						maskShape.graphics.lineStyle(1, 0xFFFFFF, 1);
						maskShape.graphics.beginFill(0xFFFFFF, 1);
						maskShape.graphics.lineTo(tW, 0);
						maskShape.graphics.lineTo(tW, tH * count );
						maskShape.graphics.curveTo(tW * count, tH * count, 0, tH * (count/2));
						maskShape.graphics.lineTo(0, 0);
						break;
					
					default:
						break;
				}

				if (count <= 0) 
				{
					mc.removeEventListener(Event.ENTER_FRAME, doWipeOut);					
					mc.parent.removeChild(mc);
				}
			}
		}
		
		public static function fadeIn(mc, duration:uint=1) 
		{
			mc.alpha = 0;
			var tweenLite:TweenLite = new TweenLite(mc,duration,{alpha:1});
		}

		public static function createBMPOverlay(mc, mc_parent, contentPlaceX, contentPlaceY) 
		{
			
			// the purpose of this function is to only show the
			// the actual tekst fields when a user is likely to select tekst
			// or otherwise do something usefull.
			// if not the content container will be replaced by a bitmap
			
			var placeHolder:MovieClip = new MovieClip();
			var snapshot:Bitmap = BitmapManipulator.mcToBitmap(mc, true, 0, 0, mc.width, mc.height, 1); // correction
			
			placeHolder.addChild(snapshot);
			placeHolder.x = contentPlaceX;
			placeHolder.y = contentPlaceY;
			
			mc_parent.addChild(placeHolder);
			mc.visible = false;
			
			placeHolder.addEventListener(MouseEvent.MOUSE_OVER, showText);

			function showText(e:Event) 
			{
				placeHolder.removeEventListener(MouseEvent.MOUSE_OVER, showText);
				mc.addEventListener(Event.ENTER_FRAME, checkMouse);
				mc.visible = true;
				placeHolder.visible = false;
			}
			
			function checkMouse(e:Event) 
			{
				if (mc.mouseX < 0 || mc.mouseX > mc.width || mc.mouseY < 0 || mc.mouseY > mc.height) 
				{
					hideText()
				}
			}
			
			function hideText() 
			{
				mc.visible = false;
				mc.removeEventListener(Event.ENTER_FRAME, checkMouse);
				placeHolder.addEventListener(MouseEvent.MOUSE_OVER, showText);
				placeHolder.visible = true;
			}
		}
		
		/**
		 * this function creates a picture from an imageloader with the desired width and height
		 * the type selects the most convenient way to scale the image
		 * the function returns a movieclip
		 * 
		 * @param	picLoader	The Loader
		 * @param	sW			Target width
		 * @param	sH			Target height
		 * @param	type		Masking type. Valid values are "scale", "scaleAspect", "masked"
		 * @return	returns a movieclip containing the bitmap
		 */ 
		public static function createPicture(picLoader:Loader, sW:int = 0, sH:int = 0, type:String = "masked"):MovieClip
		{
			var picture:MovieClip = new MovieClip();
			var loaderBMP:Bitmap = BitmapManipulator.mcToBitmap(picLoader, true, 0, 0, picLoader.width, picLoader.height, 1);
			
			//trace("scaling image ", type, picLoader.width, sW);
			
			switch(type) 
			{
				case "scale":
					
					// simply scales the picture to the assigned width and height
					
					loaderBMP.width = sW;
					loaderBMP.height = sH;
					picture.addChild(loaderBMP);
					break;
			
				case "scaleAspect":
				
					// calculated the aspect ratio of the image and scales accordingly
					
					scaleBest();
					picture.addChild(loaderBMP);
					break;
				
				case "masked":
				
					// calculated the aspect ratio of the image and scales accordingly
					// then moves the images to the center of the picture and creates a 
					// mask shape
					
					scaleBest();
					setMask();
					break;
					
				default:
				
					// do nothing
					picture.addChild(loaderBMP);
					break;
			}	
			
			// helper functions 
			function scaleBest() 
			{
			
				if (loaderBMP.width >= loaderBMP.height) 
				{
					
					// image is wider then high,
					// match width with height
					
					loaderBMP.width *= (sH/loaderBMP.height);
					loaderBMP.height = sH;

				}
				else
				{

					// image is higher then wide
					// match height with width
					
					loaderBMP.height *= (sW/loaderBMP.width);
					loaderBMP.width = sW;
				}
				
				// redo bij te klein
				if (loaderBMP.width < sW) 
				{
					loaderBMP.height *= (sW/loaderBMP.width);
					loaderBMP.width = sW;
				}
				
				if (loaderBMP.height < sH) 
				{
					loaderBMP.width *= (sH/loaderBMP.height);
					loaderBMP.height = sH;
				}
			}

			function setMask() 
			{

				var maskShape:Shape = new Shape();
				maskShape.graphics.lineStyle(1, 0x000000, 1);
				maskShape.graphics.beginFill(0x000000, 1);
				maskShape.graphics.drawRect(0, 0, sW, sH);
				
				picture.addChild(loaderBMP)
				loaderBMP.x = (sW - loaderBMP.width)/2;
				loaderBMP.y = (sH - loaderBMP.height)/2;
				
				picture.addChild(maskShape);
				loaderBMP.mask = maskShape;
			}
				
			return picture;
		}
		
		// would be nice
		public static function colorTransForm() {}
		public static function levels() {}
    }
}